/*
 *  Copyright 2012 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.pc.domain.domains;

import java.util.Comparator;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.UniqueConstraint;

/**
 *
 * @author yura
 */
@Entity
@Table(name = "publisher", uniqueConstraints = { @UniqueConstraint(
		columnNames = {"name", "second_name", "last_name" }) })
public class Publisher implements AbstractDomain<Integer>, Comparable<Publisher>{

	private static final long serialVersionUID = -1837265981732689120L;

    public static final Comparator<Publisher> FULL_COMPARE = new Comparator<Publisher>() {

        @Override
        public int compare(Publisher o1, Publisher o2) {
            int i = nullSafeCompare(o1.id, o2.id);
            if (i == 0)
                i = nullSafeCompare(o1.secondName, o2.secondName);
            if (i == 0)
                i = nullSafeCompare(o1.name, o2.name);
            if (i == 0)
                i = nullSafeCompare(o1.lastName, o2.lastName);
            return i;
        }

    };

    private static int nullSafeCompare(Comparable o1, Comparable o2){
        if (o1 == null){
            return o2 == null ? 0 : -1;
        } else if (o2 == null){
            return 1;
        } else {
            return o1.compareTo(o2);
        }
    }

	@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "name")
    private String name;

    /** surname */
    @Column(name = "second_name")
    private String secondName;//familia

    /** father name */
    @Column(name = "last_name")
    private String lastName;//otchestvo

    /**
     * Различие «студент» и «не-студент» - необходимо различать публикации
     * студентов, и все остальные публикации (например, публикации
     * преподавателей). Чьи эти «остальные» публикации нас не интересует. Важно
     * только различие: студент и !студент.
     */
    @Column(name = "is_student", nullable=false)
    private Boolean isStudent = Boolean.TRUE;

    @ManyToMany
        //(targetEntity=Publication.class, mappedBy="publicators")
    @JoinTable(name = "publication_publicators",
        joinColumns=
            @JoinColumn(name = "publicators_id", referencedColumnName = "id"),
        inverseJoinColumns=
            @JoinColumn(name = "publication_id", referencedColumnName = "id"))
    private Set<Publication> publications;

    public Publisher() {
        this(null, "", "", "");
    }

    public Publisher(Integer id, String name, String secondName, String lastName) {
        this.id = id;
        this.name = name;
        this.secondName = secondName;
        this.lastName = lastName;
    }

    @Override
    public Integer getId() {
        return id;
    }

    @Override
    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSecondName() {
        return secondName;
    }

    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }
    
    public Boolean getIsStudent() {
		return isStudent;
	}
    
    public void setIsStudent(Boolean isStudent) {
		this.isStudent = isStudent;
	}

    public Set<Publication> getPublications() {
        return publications;
    }

    public void setPublications(Set<Publication> publications) {
        this.publications = publications;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Publisher other = (Publisher) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 41 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Publisher" + id + "{name=" + name + "; secondName=" + secondName
                + "; lastName=" + lastName + '}';
    }

    @Override
    public int compareTo(Publisher o) {
        return FULL_COMPARE.compare(this, o);
    }
}
